local song = _SONG();
local pAssist={false,false};
for pn in ivalues(PlayerNumber) do
	local p=(pn==PLAYER_1) and 1 or 2;
	local nm=ToEnumShortString(pn);
	if PROFILEMAN:GetNumLocalProfiles()>0
		and (PROFILEMAN:GetProfile(PLAYER_1):GetDisplayName() ~= PROFILEMAN:GetProfile(PLAYER_2):GetDisplayName()) then
		for i=1,PROFILEMAN:GetNumLocalProfiles() do
			if PROFILEMAN:GetProfile(pn):GetDisplayName()==PROFILEMAN:GetLocalProfileFromIndex(i-1):GetDisplayName() then
				nm="["..PROFILEMAN:GetLocalProfileIDFromIndex(i-1).."]";
				break
			end;
		end;
	end;
	pAssist[p]=(GetUserPref_Theme("UserSpeedAssist"..nm)=='On');
	if not pAssist[p] then pAssist[p]=false end;
end;
local t=Def.ActorFrame{};
if not pAssist[1] and not pAssist[2] then
	return;
end;
local pStepZoneX={GetStepZonePosX(PLAYER_1),GetStepZonePosX(PLAYER_2)};
local pStepZoneY={SCREEN_CENTER_Y,SCREEN_CENTER_Y};
local now = 0.0;

local stopPosListP1;
local stopSecListP1;
local stopPosListP2;
local stopSecListP2;
local stopNowCnt;
local function setStopList(pn)
	if pn==PLAYER_1 and not GAMESTATE:IsPlayerEnabled(PLAYER_1) then
		stopPosListP1={-1};
		return;
	end;
	if pn==PLAYER_2 and not GAMESTATE:IsPlayerEnabled(PLAYER_2) then
		stopPosListP2={-1};
		return;
	end;
	local st=GAMESTATE:GetCurrentSteps(pn);
	local td=st:GetTimingData();
	if td:HasStops() then
		local strStops=td:GetStops();
		for i=1,#strStops do
			local stopData=split("=",strStops[i]);
			if pn==PLAYER_1 then
				stopPosListP1[i]=tonumber(stopData[1]);
				stopSecListP1[i]=tonumber(stopData[2]);
			else
				stopPosListP2[i]=tonumber(stopData[1]);
				stopSecListP2[i]=tonumber(stopData[2]);
			end;
		end;
	else
		if (pn==PLAYER_1) then
			stopPosListP1={-1};
		else
			stopPosListP2={-1};
		end;
	end;
end;

local now;
local function SongChk()
	local ret=false;
	if (not song) or (song ~= _SONG2()) then
		song = _SONG2();
		ret=true;
	end;
	now=_MUSICSECOND();
	return ret;
end;

local chksec=0.025;
t[#t+1]=Def.ActorFrame{
	OnCommand=function(self)
		self:queuecommand("Loop");
	end;
	LoopCommand=function(self)
		if SongChk() then
			self:finishtweening();
			self:playcommand("ChangeSong");
		end;
		self:finishtweening();
		self:visible(true);
		self:sleep(chksec);
		self:queuecommand("Loop");
	end;
	Def.Actor{
		InitCommand=function(self)
			stopPosListP1={0};
			stopSecListP1={0};
			stopPosListP2={0};
			stopSecListP2={0};
			stopNowCnt={1,1};
			setStopList(PLAYER_1);
			setStopList(PLAYER_2);
		end;
		ChangeSongCommand=function(self)
			self:playcommand("Init");
		end;
	};
	LoadActor(THEME:GetPathG("_objects/_circle","glow100px"))..{
		Name="P1Glow";
		InitCommand=cmd(diffuse,Color("Red");blend,"BlendMode_Add";
			x,pStepZoneX[1];y,pStepZoneY[1];diffusealpha,0;visible,pAssist[1];diffusealpha,0;);
		LoopCommand=function(self)
			if stopPosListP1[1]~=-1 and stopNowCnt[1]<=#stopPosListP1 then
				beat=1.0*Sec2PlayerBeat(PLAYER_1,now);
				if 1.0*beat>=stopPosListP1[stopNowCnt[1]] then
					local stopBegin=PlayerBeat2Sec(PLAYER_1,stopPosListP1[stopNowCnt[1]]);
					local stopEnd=stopBegin+stopSecListP1[stopNowCnt[1]];
					if now>=stopEnd+0.1 then
						self:diffusealpha(0);
					elseif now>=stopEnd then
						self:diffusealpha(1.0-(now-stopEnd)*10);
						self:zoom(1.0+(now-stopEnd)*10);
					elseif now<stopBegin+0.1 then
						self:diffusealpha(1.0-(stopBegin+0.1-now)*10);
						self:zoom(1.0+(stopBegin+0.1-now)*10);
					else
						self:diffusealpha(1.0);
						self:zoom(1.0);
					end;
				else
						self:diffusealpha(0);
				end;
			else
					self:diffusealpha(0);
			end;
			self:sleep(chksec);
			self:queuecommand("Loop");
		end;
	};
	LoadActor(THEME:GetPathG("_objects/_circle","100px"))..{
		Name="P1Circle";
		InitCommand=cmd(diffuse,Color("Red");blend,"BlendMode_Add";
			x,pStepZoneX[1];y,pStepZoneY[1];diffusealpha,0;visible,pAssist[1];diffusealpha,0;);
		LoopCommand=function(self)
			if stopPosListP1[1]~=-1 and stopNowCnt[1]<=#stopPosListP1 then
				beat=1.0*Sec2PlayerBeat(PLAYER_1,now);
				if 1.0*beat>=stopPosListP1[stopNowCnt[1]] then
					local stopBegin=PlayerBeat2Sec(PLAYER_1,stopPosListP1[stopNowCnt[1]]);
					local stopEnd=stopBegin+stopSecListP1[stopNowCnt[1]];
					if now>=stopEnd+0.1 then
						self:diffusealpha(0);
						stopNowCnt[1]=stopNowCnt[1]+1;
					elseif now>=stopEnd then
						self:diffusealpha(1.0-(now-stopEnd)*10);
						self:zoom(1.0+(now-stopEnd)*10);
					elseif now<stopBegin+0.1 then
						self:diffusealpha(1.0-(stopEnd-now)/stopSecListP1[stopNowCnt[1]]);
						self:zoom(1.0-(stopEnd-now)/stopSecListP1[stopNowCnt[1]]);
					else
						self:diffusealpha(1.0-(stopEnd-now)/stopSecListP1[stopNowCnt[1]]);
						self:zoom(1.0-(stopEnd-now)/stopSecListP1[stopNowCnt[1]]);
					end;
				else
						self:diffusealpha(0);
				end;
			else
					self:diffusealpha(0);
			end;
			self:sleep(chksec);
			self:queuecommand("Loop");
		end;
	};
	LoadActor(THEME:GetPathG("_objects/_circle","glow100px"))..{
		Name="P2Glow";
		InitCommand=cmd(diffuse,Color("Red");blend,"BlendMode_Add";
			x,pStepZoneX[2];y,pStepZoneY[2];diffusealpha,0;visible,pAssist[2];diffusealpha,0;);
		LoopCommand=function(self)
			if stopPosListP2[1]~=-1 and stopNowCnt[2]<=#stopPosListP2 then
				beat=1.0*Sec2PlayerBeat(PLAYER_2,now);
				if 1.0*beat>=stopPosListP2[stopNowCnt[2]] then
					local stopBegin=PlayerBeat2Sec(PLAYER_2,stopPosListP2[stopNowCnt[2]]);
					local stopEnd=stopBegin+stopSecListP2[stopNowCnt[2]];
					if now>=stopEnd+0.1 then
						self:diffusealpha(0);
					elseif now>=stopEnd then
						self:diffusealpha(1.0-(now-stopEnd)*10);
						self:zoom(1.0+(now-stopEnd)*10);
					elseif now<stopBegin+0.1 then
						self:diffusealpha(1.0-(stopBegin+0.1-now)*10);
						self:zoom(1.0+(stopBegin+0.1-now)*10);
					else
						self:diffusealpha(1.0);
						self:zoom(1.0);
					end;
				else
						self:diffusealpha(0);
				end;
			else
					self:diffusealpha(0);
			end;
			self:sleep(chksec);
			self:queuecommand("Loop");
		end;
	};
	LoadActor(THEME:GetPathG("_objects/_circle","100px"))..{
		Name="P2Circle";
		InitCommand=cmd(diffuse,Color("Red");blend,"BlendMode_Add";
			x,pStepZoneX[2];y,pStepZoneY[2];diffusealpha,0;visible,pAssist[2];diffusealpha,0;);
		LoopCommand=function(self)
			if stopPosListP2[1]~=-1 and stopNowCnt[2]<=#stopPosListP2 then
				beat=1.0*Sec2PlayerBeat(PLAYER_2,now);
				if 1.0*beat>=stopPosListP2[stopNowCnt[2]] then
					local stopBegin=PlayerBeat2Sec(PLAYER_2,stopPosListP2[stopNowCnt[2]]);
					local stopEnd=stopBegin+stopSecListP2[stopNowCnt[2]];
					if now>=stopEnd+0.1 then
						self:diffusealpha(0);
						stopNowCnt[2]=stopNowCnt[2]+1;
					elseif now>=stopEnd then
						self:diffusealpha(1.0-(now-stopEnd)*10);
						self:zoom(1.0+(now-stopEnd)*10);
					elseif now<stopBegin+0.1 then
						self:diffusealpha(1.0-(stopEnd-now)/stopSecListP2[stopNowCnt[2]]);
						self:zoom(1.0-(stopEnd-now)/stopSecListP2[stopNowCnt[2]]);
					else
						self:diffusealpha(1.0-(stopEnd-now)/stopSecListP2[stopNowCnt[2]]);
						self:zoom(1.0-(stopEnd-now)/stopSecListP2[stopNowCnt[2]]);
					end;
				else
						self:diffusealpha(0);
				end;
			else
					self:diffusealpha(0);
			end;
			self:sleep(chksec);
			self:queuecommand("Loop");
		end;
	};
};

return t;
